/**
 * This file is released under the GNU General Public License.
 * Refer to the COPYING file distributed with this package.
 *
 * Copyright (c) 2008-2009 WURFL-Pro srl
 */
package net.sourceforge.wurfl.core.resource;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

/**
 * Collection of {@link WURFLResource}.
 * 
 * @author WURFL-PRO SRL, Rome, Italy
 * @version $Id: WURFLResources.java 1045 2009-03-09 15:52:53Z filippo.deluca $
 */
public final class WURFLResources {

	/** List containing the resources */
	private final List/* WURFLResource */resources = new ArrayList();

	// Constructors *******************************************************

	/**
	 * Default constructor
	 */
	public WURFLResources() {
		// Empty
	}

	/**
	 * Constructor by WURFLResource array.
	 * 
	 * @param resources
	 *            Array of WURFLResource.
	 */
	public WURFLResources(WURFLResource[] resources) {

		Validate.notNull(resources, "The resources is null");

		this.resources.addAll(Arrays.asList(resources));
	}

	/**
	 * Constructor by WURFLResource collection.
	 * 
	 * @param resources
	 *            Collection<WURFLResource> to initialize this WURFLResources.
	 */
	public WURFLResources(Collection/* WURFLResource */resources) {

		Validate.notNull(resources, "The resources is null");
		Validate.noNullElements(resources, "The resources contains null value");
		Validate.allElementsOfType(resources, WURFLResource.class,
				"The resources contains value not instaceof WURFLResource");

		this.resources.addAll(resources);
	}

	// Business methods ***************************************************

	/**
	 * Return the size of this collection.
	 * 
	 * @return size of collection.
	 */
	public int size() {
		return resources.size();
	}

	/**
	 * Return the {@link WURFLResource} at specified index.
	 * 
	 * @param index
	 *            Index of wanted WURFLResource.
	 * @return The WURFLResouce at given index.
	 */
	public WURFLResource get(int index) {
		return (WURFLResource) resources.get(index);
	}

	/**
	 * Returns the index of given resource.
	 * 
	 * @param resource
	 *            The WURFLResource to find index.
	 * @return the index of the given WURFLResource, -1 if it does not exist.
	 */
	public int indexOf(WURFLResource resource) {

		Validate.notNull(resource, "The resource is null");

		return resources.indexOf(resource);
	}

	/**
	 * Release all held resources.
	 * 
	 * @see WURFLResource#release()
	 */
	public void release() {
		for (Iterator iterator = resources.iterator(); iterator.hasNext();) {
			WURFLResource resource = (WURFLResource) iterator.next();
			resource.release();
		}
	}

	/**
	 * Add a WURFLResource to collection.
	 * 
	 * @param resource
	 *            The WURFLResource to add.
	 */
	public void add(WURFLResource resource) {

		Validate.notNull(resource, "The resource must be not null");

		resources.add(resource);
	}

	/**
	 * Remove a resource from collection.
	 * 
	 * @param resource
	 *            The WURFLResource to remove.
	 */
	public void remove(WURFLResource resource) {

		Validate.notNull(resource, "The resource must be not null");

		resources.remove(resource);
	}

	/**
	 * Returns a resources iterator.
	 * 
	 * @return Iterator<WURFLResource> over the resources.
	 */
	public Iterator/* WURFLResource */iterator() {

		return resources.iterator();
	}

	// Commons methods ****************************************************

	public String toString() {

		return new ToStringBuilder(this).append(resources).toString();

	}

	public boolean equals(Object obj) {
		EqualsBuilder eb = new EqualsBuilder();

		eb.appendSuper(getClass().isInstance(obj));
		if (eb.isEquals()) {
			WURFLResources other = (WURFLResources) obj;
			eb.append(resources, other.resources);
		}

		return eb.isEquals();
	}

	public int hashCode() {
		HashCodeBuilder hb = new HashCodeBuilder(53, 79);

		hb.append(getClass()).append(resources);

		return hb.toHashCode();
	}

}
